﻿using System;
using Microsoft.Xna.Framework;

namespace XDL.Framework.Weapons
{
    /// <summary>
    /// Helper class to fire a weapon every X seconds
    /// </summary>
    public class WeaponEmiter
    {
        #region Fields
        readonly float m_timeBetweenFire;
        float m_timeLeftOver;
        readonly float m_firingDuration;
        readonly int m_ownerID;
        float m_remainingFiringTime;
        IWeapon m_weapon;
        #endregion

        /// <summary>
        /// Constructs a new particle emitter object.
        /// </summary>
        public WeaponEmiter(IWeapon weapon, int ownerId, float firePerSecond, float firingDuration)
        {
            m_weapon = weapon;
            m_ownerID = ownerId;
            m_timeBetweenFire = 1.0f / firePerSecond;
            m_firingDuration = firingDuration;
            m_remainingFiringTime = 0;
        }

        /// <summary>
        /// Get/Set the state of the emitter
        /// </summary>
        /// <remarks>
        /// Setting IsActive to true while the emitter is still active will do nothing.
        /// </remarks>
        public bool IsActive
        {
            get { return m_remainingFiringTime > 0; }
            set
            {
                if (value == false)
                {
                    m_remainingFiringTime = 0;
                }
                else
                {
                    // let the emitter finishes!!
                    if (m_remainingFiringTime <= 0)
                    {
                        m_timeLeftOver = 0;
                        m_remainingFiringTime = m_firingDuration;
                    }
                }
            }
        }

        /// <summary>
        /// Updates the emitter, creating the appropriate number of particles
        /// in the appropriate positions.
        /// </summary>
        public void Fire(GameTime gameTime, Vector3 position, Vector3 direction)
        {
            if (!IsActive)
                return;

            // Work out how much time has passed since the previous update.
            float elapsedTime = (float)gameTime.ElapsedGameTime.TotalSeconds;

            if (elapsedTime > 0)
            {
                // time over?
                m_remainingFiringTime -= elapsedTime;
                if (m_remainingFiringTime < 0)
                    return;

                // If we had any time left over that we didn't use during the
                // previous update, add that to the current elapsed time.
                float timeToSpend = m_timeLeftOver + elapsedTime;

                // Counter for looping over the time interval.
                float currentTime = -m_timeLeftOver;

                // Create particles as long as we have a big enough time interval.
                while (timeToSpend > m_timeBetweenFire)
                {
                    currentTime += m_timeBetweenFire;
                    timeToSpend -= m_timeBetweenFire;

                    // Work out the optimal position for this particle. This will produce
                    // evenly spaced particles regardless of the object speed, particle
                    // creation frequency, or game update rate.
                    float mu = currentTime / elapsedTime;

                    // 
                    m_weapon.Fire(m_ownerID, position, direction);
                }

                // Store any time we didn't use, so it can be part of the next update.
                m_timeLeftOver = timeToSpend;
            }
        }
    }
}
